package com.gitee.neuray.security.admin.executor.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gitee.neuray.security.admin.executor.qiyehao.entity.StaffVO;
import com.gitee.neuray.security.admin.executor.qiyehao.mapper.OrgDepartQyhMapper;
import com.gitee.neuray.security.admin.executor.qiyehao.mapper.StaffVOMapper;
import com.gitee.neuray.security.common.util.CommonUtil;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 时间 2020/3/10
 *
 * @author wwj
 * 企业号数据与本地对比并同步数据到企业号
 */
@Component
@Slf4j
public class QiYeHaoTaskjob {
    @Value("${weixin.qyh.corpid}")
    private  String corpid ;
    @Value("${weixin.qyh.corpsecret}")
    private  String corpsecret ;//应用secret
    @Value("${weixin.qyh.txlcecret}")
    private  String TxlCecret;//通讯录secret
    private static String token; // token
    private static final String rootDepId = "1";//企业根部门id
    @Autowired
    private OrgDepartQyhMapper orgDepartQyhMapper;
    @Autowired
    private StaffVOMapper staffVOMapper;
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 定时更新企业号人员信息
     */
    @XxlJob("QyHTasHandler")
    public ReturnT<String> QyhTasHandler(String param) throws Exception {
        XxlJobLogger.log(">>>>>>>>>>>>>>>>>>>>>>>>定时更新企业号人员信息......");
        getTocekn();//获取token
        getDepartmentsUsers();//同步部门-----加，部门映射表--部门ID-------------无需递归取子部门，接口返回在同一级
//        insertUsers();//新增用户
        deleteUsers();//删除用户------加，已删除表---避免重复删除
        return ReturnT.SUCCESS;
    }

    /**
     * 时间 2020/3/16
     *
     * @author wwj
     * 获取token
     */
    public void getTocekn() {
        Map<String, String> params = new HashMap<>();
        params.put("corpid", corpid);
        params.put("corpsecret", TxlCecret);
        String aa = null;
        try {
            aa = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}&corpsecret={corpsecret}", String.class, params);
        } catch (RestClientException e) {
            XxlJobLogger.log("==============================企业号人员信息同步获取token报错");
            XxlJobLogger.log(CommonUtil.getExceptionDtail(e));
            log.error("==============================企业号人员信息同步获取token报错");
            log.error(CommonUtil.getExceptionDtail(e));
        }
        JSONObject bb = JSONObject.parseObject(aa);
        token = bb.getString("access_token");
        XxlJobLogger.log(">>>>>>>>>>>>>>>企业号获取token......" + token);
        log.info("==============================企业号人员信息同步 token "+token);
    }

    /**
     * 时间 2020/3/16
     *
     * @author wwj
     * 同步部门信息(部门关系表)并返回所有员工集合(获取所有部门下的所有员工进而得到所有员工)
     */
    public void getDepartmentsUsers() {
        XxlJobLogger.log("====================企业号定时人员信息：getDepartmentsUsers");
        log.info("====================企业号定时人员信息：getDepartmentsUsers");
//        List<Long> departmentIds=new ArrayList<>();

        Map<String, String> params = new HashMap<>();
        params.put("access_token", token);  //
        String aa = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token={access_token}", String.class, params);
        JSONObject bb = JSONObject.parseObject(aa);
        List<JSONObject> depList = JSONArray.parseArray(bb.getString("department"), JSONObject.class);
//        List<String> departids=new ArrayList<>();
        //员工表list
//部门同步
       /* for (JSONObject j : depList) {
//            departids.add(j.get("id").toString());
            //通过关系表企业号部门id查询本地部门
            OrgVO orgVO = orgDepartQyhMapper.selOrgByDepartId(j.get("id").toString());
            if (orgVO != null) {
                //若本地部门与企业号部门名称不一样则将企业号部门名称修改与本地一致
                if (!orgVO.getOrgName().equals(j.getString("name"))) {
                    j.put("name", orgVO.getOrgName());
                    String postResult = restTemplate.postForObject("https://qyapi.weixin.qq.com/cgi-bin/department/update?access_token=" + token, j, String.class);
                    JSONObject cc = JSONObject.parseObject(postResult);
                    System.out.println("修改结果-------------------" + cc);
                }
            } else {//若对象为空则说明关系表无相关数据
                //新增关系表数据
                orgVO = orgDepartQyhMapper.selOrgByOrgName(j.get("name").toString());//通过部门名称查询部门信息
                if(orgVO!=null){
                    OrgDepartQyh orgDepartQyh = new OrgDepartQyh();
                    orgDepartQyh.setOrgId(orgVO.getId());
                    orgDepartQyh.setDepartId(j.get("id").toString());
                    orgDepartQyhMapper.insertOrgDepartQyh(orgDepartQyh);
                }

            }
        }*/
        Map<String, String> paramss = new HashMap<>();
        paramss.put("access_token", token);  //
        paramss.put("department_id", rootDepId);  //部门ID
        paramss.put("fetch_child", "1");//递归子目录
        String ac = null;
        List<JSONObject> userList = new ArrayList<>();
        try {
            ac = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token={access_token}&department_id={department_id}&fetch_child={fetch_child}", String.class, paramss);
        } catch (RestClientException e) {
            XxlJobLogger.log("==================企业微信号，获取人员信息");
            XxlJobLogger.log(CommonUtil.getExceptionDtail(e));
            log.error("==================企业微信号，获取人员信息");
            log.error(CommonUtil.getExceptionDtail(e));
        }
        JSONObject bc = JSONObject.parseObject(ac);
        //若部门下无员工，userlist为空
        userList = JSONArray.parseArray(bc.getString("userlist"), JSONObject.class);
        //删除关系表中企业号部门id不存在的数据
//        orgDepartQyhMapper.delOrgDepartQyh(departids);
        //查询出企业号中不存在部门集合---树形结构----暂时不做
        XxlJobLogger.log("===========================员工列表:" +userList);
        log.info("===========================员工列表:" +userList);
        this.insertUsers(userList);
    }

    /**
     * 时间 2020/3/16
     *
     * @author wwj
     * 新增用户
     */
    public void insertUsers(List<JSONObject> qiyehaoUserList) {
        XxlJobLogger.log("====================企业号定时人员信息：insertUsers");
        log.info("====================企业号定时人员信息：insertUsers");
        //取出所有企业号职工的电话号
        /*List<String> userPhones = new ArrayList<>();
        for (JSONObject j : qiyehaoUserList) {
            userPhones.add(j.get("mobile").toString());
        }*/
        //查询本地所有在员工----通过电话号查询其他所有在职员工
        //List<StaffVO> staffList = staffVOMapper.selectZzYg(userPhones);
        //查询本地所有在员工
        List<StaffVO> staffList = staffVOMapper.selectZzYg();
        List<StaffVO> addStaffList = new ArrayList<>();
        //对比新增员工
        if (staffList != null && staffList.size() > 0) {
            for (int i = 0; i < staffList.size(); i++) {
                boolean addFlg = true;
                for(int j = 0;j<qiyehaoUserList.size();j++){
                    //先判断电话号是否存在
                    if(qiyehaoUserList.get(j).get("mobile").toString().equals(staffList.get(i).getPhone())){
                        addFlg = false;
                        break;
                    }
                    //判断邮箱是否存在
                    if(qiyehaoUserList.get(j).get("email").toString().equals(staffList.get(i).getEmail())){
                        addFlg = false;
                        break;
                    }
                }
                //如果企业号没有新增
                if(addFlg){
                    addStaffList.add(staffList.get(i));
                }
            }
        }
        //新增员工
        /*//todo 测试
        for(int i=addStaffList.size()-1;i>=0;i--){
            if(!addStaffList.get(i).getName().equals("范娇")){
                addStaffList.remove(i);
            }
        }*/
        if (addStaffList.size() > 0) {
            for (int i = 0; i < addStaffList.size(); i++) {
                JSONObject userjson = new JSONObject();
                //新增的人员都是电话号主键
                userjson.put("userid", addStaffList.get(i).getPhone());
                userjson.put("name", addStaffList.get(i).getName());
//                userjson.put("alias",);
                userjson.put("mobile", addStaffList.get(i).getPhone());
                userjson.put("department", addStaffList.get(i).getQyhDeptId());
                userjson.put("order", "0");
                userjson.put("position", addStaffList.get(i).getPosition());
                String sex = ((addStaffList.get(i).getSex()==null)?"1":addStaffList.get(i).getSex());
                if(sex.equals("女")){
                    sex = "2";
                }else {
                    sex = "1";
                }
                userjson.put("gender", sex);
                userjson.put("email", addStaffList.get(i).getEmail());
                userjson.put("is_leader_in_dept", "0");
                userjson.put("enable", "1");
                userjson.put("telephone", addStaffList.get(i).getPhone());
                userjson.put("address", addStaffList.get(i).getZz());
                String aa = null;
                try {
                    aa = restTemplate.postForObject("https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token=" + token, userjson, String.class);
                    //获取openid begin
                    //这里获取不到openid 需要成员扫描关注后才行
                    String openId = getOpenid(userjson.getString("userid"));
                    staffVOMapper.updateQyhId(addStaffList.get(i).getId(),userjson.getString("userid"),openId);
                    //获取openid end
                } catch (RestClientException e) {
                    XxlJobLogger.log("======================企业号新增人员出错："+userjson.toJSONString());
                    XxlJobLogger.log(CommonUtil.getExceptionDtail(e));
                    log.error("======================企业号新增人员出错："+userjson.toJSONString());
                    log.error(CommonUtil.getExceptionDtail(e));
                }
                JSONObject bb = JSONObject.parseObject(aa);
                XxlJobLogger.log("==========================企业号新增人员："+bb.toJSONString());
                XxlJobLogger.log("==========================企业号新增人员："+addStaffList.get(i).toString());
                log.info("==========================企业号新增人员："+bb.toJSONString());
                log.info("==========================企业号新增人员："+addStaffList.get(i).toString());
            }
        }
        XxlJobLogger.log("====================企业号定时人员信息：insertUsers结束");
        log.info("====================企业号定时人员信息：insertUsers结束");
    }

    /**
     * 时间 2020/3/16
     *
     * @author wwj
     * 删除员工
     */
    public void deleteUsers() {
        XxlJobLogger.log("====================企业号定时人员信息：deleteUsers");
        log.info("====================企业号定时人员信息：deleteUsers");
        Map<String, String> params = new HashMap<>();
        params.put("access_token", token);
        //查询出已删除表之外的离职员工
        List<StaffVO> staffList = staffVOMapper.selectLzYg();
        if (staffList != null && staffList.size() > 0) {
            for (StaffVO s : staffList) {
                params.put("userid", s.getPhone());
                String ac = null;
                //删除人员主键大多是手机号，但是部分早期加入的人员是account或者邮件，也可能三个都不是，那就得需要手动删除了
                try {
                    ac = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/user/delete?access_token={access_token}&userid={userid}", String.class, params);
                    JSONObject bc0 = JSONObject.parseObject(ac);
                    if(bc0.getString("errcode").equals("60111")){//如果删除失败，说明主键不是电话号
                        params.put("userid", s.getAccout());
                        ac = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/user/delete?access_token={access_token}&userid={userid}", String.class, params);
                        JSONObject bc1 = JSONObject.parseObject(ac);
                        if(bc1.getString("errcode").equals("60111")){//如果删除失败，说明主键不是电话号 也不是account
                            params.put("userid", s.getEmail());
                            ac = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/user/delete?access_token={access_token}&userid={userid}", String.class, params);
                        }
                    }
                    //每删除一条新增一条删除表数据
                    staffVOMapper.insertQyhDeleted(s.getId());
                } catch (RestClientException e) {
                    XxlJobLogger.log("===========企业号删除人员报错:"+s.getId());
                    XxlJobLogger.log(CommonUtil.getExceptionDtail(e));
                    log.error("===========企业号删除人员报错:"+s.getId());
                    log.error(CommonUtil.getExceptionDtail(e));
                }
                JSONObject bc = JSONObject.parseObject(ac);
                XxlJobLogger.log("=============删除人员："+bc.toJSONString());
                XxlJobLogger.log("=============删除人员："+s.toString());
                log.info("=============删除人员："+bc.toJSONString());
                log.info("=============删除人员："+s.toString());

            }

        }
        XxlJobLogger.log("====================企业号定时人员信息：deleteUsers 结束");
        log.info("====================企业号定时人员信息：deleteUsers 结束");
    }

    /**
     * 获取openid
     * @param userId
     * @return
     */
    private String getOpenid(String userId){
        String res = "0";
        String openidUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid?access_token=" + token;
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        Map<String,String> map = new HashMap<>();
        map.put("userid",userId);

        try {
            httpClient = HttpClients.createDefault();
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000).build();
            httpPost = new HttpPost(openidUrl);
            httpPost.setHeader("Content-type", "application/json");
            httpPost.setConfig(requestConfig);
            httpPost.setEntity(new StringEntity(JSONObject.toJSONString(map)));
            CloseableHttpResponse response = httpClient.execute(httpPost);
            org.apache.http.HttpEntity httpEntity = response.getEntity();
            JSONObject json =JSON.parseObject(EntityUtils.toString(httpEntity,"utf-8"));
            res = json.getString("openid");
        } catch (ClientProtocolException e) {
            log.error("===========企业号获取openid报错:"+CommonUtil.getExceptionDtail(e));
        } catch (IOException e) {
            log.error("===========企业号获取openid报错:"+CommonUtil.getExceptionDtail(e));
        }finally{
            try {
                if(httpPost!=null){
                    httpPost.releaseConnection();
                }
                if(httpClient!=null){
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    /**
     * 处理企业号人员id openid 历史数据
     */
    private void dealQyhIdHisData (){
        Map<String, String> paramss = new HashMap<>();
        paramss.put("access_token", token);  //
        paramss.put("department_id", rootDepId);  //部门ID
        paramss.put("fetch_child", "1");//递归子目录
        String ac = null;
        List<JSONObject> userList = new ArrayList<>();
        try {
            ac = restTemplate.getForObject("https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token={access_token}&department_id={department_id}&fetch_child={fetch_child}", String.class, paramss);
            JSONObject bc = JSONObject.parseObject(ac);
            //若部门下无员工，userlist为空
            userList = JSONArray.parseArray(bc.getString("userlist"), JSONObject.class);
            for(JSONObject jsn:userList){
                String userid = jsn.getString("userid");
                String mobile = jsn.getString("mobile");
                String openid = getOpenid(userid);
                staffVOMapper.updateQyhIdByMobile(mobile,userid,openid);
            }
        } catch (RestClientException e) {
            XxlJobLogger.log("==================企业微信号，获取人员信息");
            XxlJobLogger.log(CommonUtil.getExceptionDtail(e));
            log.error("==================企业微信号，获取人员信息");
            log.error(CommonUtil.getExceptionDtail(e));
        }

    }
}
